--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 637fd52785f38f0d864d05cd6e05adfc179705c6
Parents : e245c1a
Author : Mark Qvist <bc7291552be7a58f361522990465165c>
Signature : T66BB85Valid, signed by author
Date : 2026-07-21T16:06:23+02:00
View telemetry interfaces directly from object details
Changes
4 files changed, 160 insertions(+), 135 deletions(-)
Diff
diff --git a/sbapp/main.py b/sbapp/main.py
index 8cd0161c..07abfa5a 100644
--- a/sbapp/main.py
+++ b/sbapp/main.py
@@ -610,7 +610,6 @@ class SidebandApp(MDApp):
self.incoming_messages_updater = None
self.last_map_update = 0
self.last_telemetry_received = 0
- self.telemetry_interfaces = {}
self.repository_url = None
self.rnode_flasher_url = None
@@ -1889,7 +1888,7 @@ class SidebandApp(MDApp):
self.telemetry_action(self)
if text == "y":
- self.map_display_own_telemetry()
+ self.map_display_own_telemetry(from_keyboard=True)
if text == "u":
self.utilities_action()
@@ -5150,9 +5149,9 @@ class SidebandApp(MDApp):
except Exception as e: RNS.log(f"Could not request telemetry update: {e}", RNS.LOG_ERROR)
else: self.object_details_action(sender)
- def map_display_own_telemetry(self, sender=None):
+ def map_display_own_telemetry(self, sender=None, from_keyboard=False):
self.sideband.update_telemetry()
- self.object_details_action(source_dest=self.sideband.lxmf_destination.hash,from_telemetry=True)
+ self.object_details_action(source_dest=self.sideband.lxmf_destination.hash,from_telemetry=not from_keyboard, from_convs=from_keyboard)
def map_object_list(self, sender): pass
@@ -5167,32 +5166,6 @@ class SidebandApp(MDApp):
if not self.if_discovery: self.if_discovery = RNS.Discovery.InterfaceDiscovery(discover_interfaces=False)
return self.if_discovery.list_discovered_interfaces()
- def iface_icon(self, iface_type):
- if iface_type == "RNodeInterface": return "access-point-network"
- elif iface_type == "WeaveInterface": return "access-point"
- elif iface_type == "KISSInterface": return "radio-tower"
- elif iface_type == "BackboneInterface": return "wan"
- elif iface_type == "TCPServerInterface": return "lan-connect"
- elif iface_type == "I2PInterface": return "lock-pattern"
- elif iface_type == "connection": return "transit-connection-variant"
- elif iface_type == "blocked": return "close-octagon"
- elif iface_type.startswith("signal-"):
- try: strength = int(iface_type.replace("signal-", ""))
- except Exception as e: return "wifi-strength-off-outline"
- if strength > 80: return "wifi-strength-4"
- elif strength > 60: return "wifi-strength-3"
- elif strength > 40: return "wifi-strength-2"
- elif strength > 20: return "wifi-strength-1"
- else: return "wifi-strength-outline"
-
- return "lan-connect"
-
- def iface_appearance(self, iface_type):
- connection_types = ["connection", "blocked"]
- if iface_type in connection_types or iface_type.startswith("signal-"): f = 0.95; a = 1.0
- else: f = 0.8; a = 1.0
- return [self.iface_icon(iface_type), [255/255, 253/255, 231/255, a], [75/255*f, 97/255*f, 108/255*f, a]]
-
### Object details screen
######################################
diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py
index 67da5542..7819367b 100644
--- a/sbapp/sideband/core.py
+++ b/sbapp/sideband/core.py
@@ -167,6 +167,7 @@ class SidebandCore():
self.latest_packed_telemetry = None
self.telemetry_changes = 0
self.telemetry_response_excluded = []
+ self.telemetry_interfaces = {}
self.pending_telemetry_send = False
self.pending_telemetry_send_try = 0
self.pending_telemetry_send_maxtries = 2
@@ -1331,6 +1332,118 @@ class SidebandCore():
else:
return None
+ def iface_icon(self, iface_type):
+ if iface_type == "RNodeInterface": return "access-point-network"
+ elif iface_type == "WeaveInterface": return "access-point"
+ elif iface_type == "KISSInterface": return "radio-tower"
+ elif iface_type == "BackboneInterface": return "wan"
+ elif iface_type == "TCPServerInterface": return "lan-connect"
+ elif iface_type == "I2PInterface": return "lock-pattern"
+ elif iface_type == "connection": return "transit-connection-variant"
+ elif iface_type == "blocked": return "close-octagon"
+ elif iface_type.startswith("signal-"):
+ try: strength = int(iface_type.replace("signal-", ""))
+ except Exception as e: return "wifi-strength-off-outline"
+ if strength > 80: return "wifi-strength-4"
+ elif strength > 60: return "wifi-strength-3"
+ elif strength > 40: return "wifi-strength-2"
+ elif strength > 20: return "wifi-strength-1"
+ else: return "wifi-strength-outline"
+
+ return "lan-connect"
+
+ def iface_appearance(self, iface_type):
+ connection_types = ["connection", "blocked"]
+ if iface_type in connection_types or iface_type.startswith("signal-"): f = 0.95; a = 1.0
+ else: f = 0.8; a = 1.0
+ return [self.iface_icon(iface_type), [255/255, 253/255, 231/255, a], [75/255*f, 97/255*f, 108/255*f, a]]
+
+ def telemetry_iface_from_ife(self, ife, context_dest, ifts=None, appearance=None):
+ ifn = ife["name"]
+ if not ifts: ifts = time.time()
+ if_appearance = appearance or self.iface_appearance(ife["type"])
+ discovery_hash = RNS.Identity.full_hash(context_dest+ifn.encode("utf-8"))
+ iface = { "name": ifn, "type": ife["type"], "transport": ife["transport"], "transport_id": ife["transport_id"], "network_id": ife["network_id"],
+ "received": ifts, "last_heard": ifts, "stamp": None, "value": None, "hops": None, "heard_count": None,
+ "reachable_on": ife["reachable_on"], "port": ife["port"], "status": "available", "status_code": 1000,
+ "latitude": ife["lat"], "longitude": ife["lon"], "height": ife["height"], "if_appearance": if_appearance,
+ "frequency": ife["frequency"], "bandwidth": ife["bandwidth"], "channel": ife["channel"], "config_entry": None,
+ "modulation": ife["modulation"], "cr": ife["codingrate"], "sf": ife["spreadingfactor"] }
+
+ self.config_entry_from_iface(iface)
+ self.telemetry_interfaces[discovery_hash] = iface
+ return iface
+
+ def config_entry_from_iface(self, info):
+ try:
+ interface_type = info["type"]
+ if interface_type in ["BackboneInterface", "TCPServerInterface"]:
+ backbone_support = not RNS.vendor.platformutils.is_windows()
+ connection_interface = "BackboneInterface" if backbone_support else "TCPClientInterface"
+ remote_str = "remote" if backbone_support else "target_host"
+ cfg_name = info["name"]
+ cfg_remote = info["reachable_on"]
+ cfg_port = info["port"]
+ cfg_identity = info["transport_id"]
+ cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
+ cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
+ cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
+ cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
+ cfg_identity_str = f"\n transport_identity = {cfg_identity}"
+ info["config_entry"] = f"[[{cfg_name}]]\n type = {connection_interface}\n enabled = yes\n {remote_str} = {cfg_remote}\n target_port = {cfg_port}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
+
+ if interface_type == "I2PInterface":
+ cfg_name = info["name"]
+ cfg_remote = info["reachable_on"]
+ cfg_identity = info["transport_id"]
+ cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
+ cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
+ cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
+ cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
+ cfg_identity_str = f"\n transport_identity = {cfg_identity}"
+ info["config_entry"] = f"[[{cfg_name}]]\n type = I2PInterface\n enabled = yes\n peers = {cfg_remote}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
+
+ if interface_type == "RNodeInterface":
+ cfg_name = info["name"]
+ cfg_frequency = info["frequency"]
+ cfg_bandwidth = info["bandwidth"]
+ cfg_sf = info["sf"]
+ cfg_cr = info["cr"]
+ cfg_identity = info["transport_id"]
+ cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
+ cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
+ cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
+ cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
+ cfg_identity_str = f"\n transport_identity = {cfg_identity}"
+ info["config_entry"] = f"[[{cfg_name}]]\n type = RNodeInterface\n enabled = yes\n port = \n frequency = {cfg_frequency}\n bandwidth = {cfg_bandwidth}\n spreadingfactor = {cfg_sf}\n codingrate = {cfg_cr}\n txpower = {cfg_netname_str}{cfg_netkey_str}"
+
+ if interface_type == "WeaveInterface":
+ cfg_name = info["name"]
+ cfg_identity = info["transport_id"]
+ cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
+ cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
+ cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
+ cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
+ cfg_identity_str = f"\n transport_identity = {cfg_identity}"
+ info["config_entry"] = f"[[{cfg_name}]]\n type = WeaveInterface\n enabled = yes\n port = {cfg_netname_str}{cfg_netkey_str}"
+
+ if interface_type == "KISSInterface":
+ cfg_name = info["name"]
+ cfg_frequency = info["frequency"]
+ cfg_bandwidth = info["bandwidth"]
+ cfg_modulation = info["modulation"]
+ cfg_identity = info["transport_id"]
+ cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
+ cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
+ cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
+ cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
+ cfg_identity_str = f"\n transport_identity = {cfg_identity}"
+ info["config_entry"] = f"[[{cfg_name}]]\n type = KISSInterface\n enabled = yes\n port = \n # Frequency: {cfg_frequency}\n # Bandwidth: {cfg_bandwidth}\n # Modulation: {cfg_modulation}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
+
+ except Exception as e: RNS.log(f"Error while generating config entry for interface: {e}\n{info}", RNS.LOG_ERROR)
+
+ return info["config_entry"] if "config_entry" in info else None
+
def outbound_telemetry_finished(self, message):
if message.state == LXMF.LXMessage.FAILED and hasattr(message, "try_propagation_on_fail") and message.try_propagation_on_fail:
RNS.log("Direct delivery of telemetry update "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE)
diff --git a/sbapp/ui/map.py b/sbapp/ui/map.py
index bcaa2eef..5533e758 100644
--- a/sbapp/ui/map.py
+++ b/sbapp/ui/map.py
@@ -621,7 +621,7 @@ class Map():
self.interface_discovery_hashes[telemetry_source] = iface
if "latitude" in iface and "longitude" in iface and iface["latitude"] and iface["longitude"]:
if not telemetry_source in self.clustered_markers:
- if_appearance = self.app.iface_appearance(iface["type"])
+ if_appearance = self.app.sideband.iface_appearance(iface["type"])
telemetry = {"location": {"latitude": iface["latitude"], "longitude": iface["longitude"], "last_update": time.time()}}
marker = self.create_clustered_marker(telemetry_source, telemetry, if_appearance)
if marker != None:
@@ -680,18 +680,11 @@ class Map():
ife = own_interfaces[ifn]
ifts = own_telemetry["time"]["utc"]
discovery_hash = RNS.Identity.full_hash(own_address+ifn.encode("utf-8"))
- if_appearance = self.app.iface_appearance(ife["type"])
+ if_appearance = self.app.sideband.iface_appearance(ife["type"])
if_appearance[1] = own_appearance[1]
if_appearance[2] = own_appearance[2]
- config_entry = None
- iface = { "name": ifn, "type": ife["type"], "transport": ife["transport"], "transport_id": ife["transport_id"], "network_id": ife["network_id"],
- "received": ifts, "last_heard": ifts, "stamp": None, "value": None, "hops": None, "heard_count": None,
- "reachable_on": ife["reachable_on"], "port": ife["port"], "status": "available", "status_code": 1000,
- "latitude": ife["lat"], "longitude": ife["lon"], "height": ife["height"], "if_appearance": if_appearance,
- "frequency": ife["frequency"], "bandwidth": ife["bandwidth"], "channel": ife["channel"], "config_entry": config_entry,
- "modulation": ife["modulation"], "cr": ife["codingrate"], "sf": ife["spreadingfactor"] }
+ iface = self.app.sideband.telemetry_iface_from_ife(ife, own_address, ifts=ifts, appearance=if_appearance)
self.interface_discovery_hashes[discovery_hash] = iface
- self.app.telemetry_interfaces[discovery_hash] = iface
if iface["latitude"] and iface["longitude"]:
if not discovery_hash in self.clustered_markers:
telemetry = {"location": {"latitude": iface["latitude"], "longitude": iface["longitude"], "last_update": time.time()}}
@@ -777,18 +770,11 @@ class Map():
ife = tifs[ifn]
ifts = telemetry["time"]["utc"]
discovery_hash = RNS.Identity.full_hash(telemetry_source+ifn.encode("utf-8"))
- if_appearance = self.app.iface_appearance(ife["type"])
+ if_appearance = self.app.sideband.iface_appearance(ife["type"])
if_appearance[1] = appearance[1]
if_appearance[2] = appearance[2]
- config_entry = None
- iface = { "name": ifn, "type": ife["type"], "transport": ife["transport"], "transport_id": ife["transport_id"], "network_id": ife["transport_id"],
- "received": ifts, "last_heard": ifts, "stamp": None, "value": None, "hops": None, "heard_count": None,
- "reachable_on": ife["reachable_on"], "port": ife["port"], "status": "available", "status_code": 1000,
- "latitude": ife["lat"], "longitude": ife["lon"], "height": ife["height"], "if_appearance": if_appearance,
- "frequency": ife["frequency"], "bandwidth": ife["bandwidth"], "channel": ife["channel"], "config_entry": config_entry,
- "modulation": ife["modulation"], "cr": ife["codingrate"], "sf": ife["spreadingfactor"] }
+ iface = self.app.sideband.telemetry_iface_from_ife(ife, telemetry_source, ifts=ifts, appearance=if_appearance)
self.interface_discovery_hashes[discovery_hash] = iface
- self.app.telemetry_interfaces[discovery_hash] = iface
if iface["latitude"] and iface["longitude"]:
if not discovery_hash in self.clustered_markers:
if_telemetry = {"location": {"latitude": iface["latitude"], "longitude": iface["longitude"], "last_update": time.time()}}
@@ -824,13 +810,13 @@ class Map():
if not p_hash in self.clustered_markers:
is_blocked = False
if "type_label" in p and p["type_label"] == "blocked":
- if_appearance = self.app.iface_appearance("blocked")
+ if_appearance = self.app.sideband.iface_appearance("blocked")
is_blocked = True
elif "signal" in p and "q" in p["signal"] and p["signal"]["q"] != None:
try: signal_q = int(p["signal"]["q"])
except Exception as e: signal_q = "invalid"
- if_appearance = self.app.iface_appearance(f"signal-{signal_q}")
- else: if_appearance = self.app.iface_appearance("connection")
+ if_appearance = self.app.sideband.iface_appearance(f"signal-{signal_q}")
+ else: if_appearance = self.app.sideband.iface_appearance("connection")
if source_appearance:
if_appearance[1] = source_appearance[1]
if_appearance[2] = source_appearance[2]
diff --git a/sbapp/ui/objectdetails.py b/sbapp/ui/objectdetails.py
index 55cd1cc3..7fc9a01c 100644
--- a/sbapp/ui/objectdetails.py
+++ b/sbapp/ui/objectdetails.py
@@ -39,7 +39,8 @@ class ObjectDetails():
self.app = app
self.widget = None
self.object_hash = object_hash
- self.lastest_timestamp = 0
+ self.current_appearance = None
+ self.latest_timestamp = 0
self.coords = None
self.raw_telemetry = None
self.from_telemetry = False
@@ -91,7 +92,7 @@ class ObjectDetails():
latest_telemetry = self.app.sideband.peer_telemetry(self.object_hash, limit=1)
if latest_telemetry != None and len(latest_telemetry) > 0:
telemetry_timestamp = latest_telemetry[0][0]
- if telemetry_timestamp > self.lastest_timestamp:
+ if telemetry_timestamp > self.latest_timestamp:
self.reload_telemetry(notoast=True)
def close_action(self, sender=None):
@@ -179,8 +180,8 @@ class ObjectDetails():
Clock.schedule_once(cb, 1.0)
def get_interface_data(self, discovery_hash):
- if discovery_hash in self.app.telemetry_interfaces:
- telemetry_iface = self.app.telemetry_interfaces[discovery_hash]
+ if discovery_hash in self.app.sideband.telemetry_interfaces:
+ telemetry_iface = self.app.sideband.telemetry_interfaces[discovery_hash]
else: telemetry_iface = None
if not telemetry_iface:
@@ -194,8 +195,8 @@ class ObjectDetails():
iface = telemetry_iface or if_map[discovery_hash]
if not iface: return None, None, None, None
- ts = iface["last_heard"]
- t = Telemeter()
+ ts = iface["last_heard"]
+ t = Telemeter()
if "latitude" in iface and "longitude" in iface and iface["latitude"] and iface["longitude"]:
t.sensors["time"].data = {"utc":int(ts)}
t.synthesize("location")
@@ -208,7 +209,7 @@ class ObjectDetails():
t.sensors["location"].stale_time = 12*60*60
telemetry = [[ts, t.packed()]]
- if_appearance = iface["if_appearance"] if "if_appearance" in iface else self.app.iface_appearance(iface["type"])
+ if_appearance = iface["if_appearance"] if "if_appearance" in iface else self.app.sideband.iface_appearance(iface["type"])
return telemetry, iface["name"], if_appearance, iface
def set_source(self, source_dest, from_conv=False, from_convs=False, from_objects=False, from_telemetry=False, prefetched=None):
@@ -224,11 +225,15 @@ class ObjectDetails():
self.viewing_interface = True
prefetched, if_name, if_appearance, if_data = self.get_interface_data(self.object_hash)
telemetry_allowed = False
- if not "config_entry" in if_data or not if_data["config_entry"]: config_entry_from_iface(if_data)
- self.interface_lat = if_data["latitude"] if "latitude" in if_data else None
- self.interface_lon = if_data["longitude"] if "longitude" in if_data else None
- self.interface_config = if_data["config_entry"] if "config_entry" in if_data else None
- self.interface_data = if_data
+ if not if_data:
+ RNS.log(f"Interface data for {RNS.prettyhexrep(self.object_hash)} not found", RNS.LOG_ERROR)
+ self.close_action()
+ else:
+ if not "config_entry" in if_data or not if_data["config_entry"]: self.app.sideband.config_entry_from_iface(if_data)
+ self.interface_lat = if_data["latitude"] if "latitude" in if_data else None
+ self.interface_lon = if_data["longitude"] if "longitude" in if_data else None
+ self.interface_config = if_data["config_entry"] if "config_entry" in if_data else None
+ self.interface_data = if_data
else:
self.viewing_interface = False
@@ -277,6 +282,7 @@ class ObjectDetails():
self.telemetry_list.data = []
pds = if_name or multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(source_dest))).encode("utf-8")).decode("utf-8")
appearance = if_appearance or self.app.sideband.peer_appearance(source_dest)
+ self.current_appearance = appearance
self.screen.ids.name_label.text = pds
if source_dest == own_address: self.screen.ids.name_label.text = pds+" (this device)"
@@ -309,7 +315,7 @@ class ObjectDetails():
if latest_telemetry != None and len(latest_telemetry) > 0:
telemetry_timestamp = latest_telemetry[0][0]
- self.lastest_timestamp = telemetry_timestamp
+ self.latest_timestamp = telemetry_timestamp
telemeter = Telemeter.from_packed(latest_telemetry[0][1])
self.raw_telemetry = telemeter.read_all()
@@ -501,6 +507,14 @@ class RVDetails(MDRecycleView):
if "value" in if_data: self.entries.append({"icon": "postage-stamp", "text": f"Stamp value [b]{if_data['value']}[/b]", "on_release": pass_job})
if "heard_count" in if_data: self.entries.append({"icon": "counter", "text": f"[b]Heard {if_data['heard_count']}[/b] time{'' if if_data['heard_count'] == 1 else 's'}", "on_release": pass_job})
+ def interface_action_factory(discovery_hash):
+ oh = discovery_hash; fc = self.delegate.from_conv; fcs = self.delegate.from_convs
+ fo = self.delegate.from_objects; ft = self.delegate.from_telemetry
+ def f():
+ RNS.log(f"{RNS.prettyhexrep(oh)}")
+ self.delegate.set_source(oh, from_conv=fc, from_convs=fcs, from_objects=fo, from_telemetry=ft)
+ return f
+
rendered_telemetry.sort(key=lambda s: sort[s["name"]] if s["name"] in sort else 1000)
for s in rendered_telemetry:
try:
@@ -990,7 +1004,15 @@ class RVDetails(MDRecycleView):
elif ift == "I2PInterface": ifc = f" on [b]{ife['reachable_on']}[/b]"
else: ifc = f""
- extra_entries.append({"icon": ifi, "text": f"{n}{ifc}", "on_release": pass_job})
+ discovery_hash = RNS.Identity.full_hash(self.delegate.object_hash+n.encode("utf-8"))
+ ifts = self.delegate.latest_timestamp
+ if not self.delegate.current_appearance: if_appearance = None
+ else:
+ if_appearance = self.app.sideband.iface_appearance(ife["type"])
+ if_appearance[1] = self.delegate.current_appearance[1]
+ if_appearance[2] = self.delegate.current_appearance[2]
+ self.app.sideband.telemetry_iface_from_ife(ife, self.delegate.object_hash, ifts=ifts, appearance=if_appearance)
+ extra_entries.append({"icon": ifi, "text": f"{n}{ifc}", "on_release": interface_action_factory(discovery_hash)})
elif name == "LXMF Propagation":
tp = str(s["values"]["total_peers"])
@@ -1093,75 +1115,6 @@ class RVDetails(MDRecycleView):
RNS.log(f"An {str(type(e))} occurred while updating service telemetry: {str(e)}", RNS.LOG_ERROR)
RNS.log(exception_info, RNS.LOG_ERROR)
-def config_entry_from_iface(info):
- try:
- interface_type = info["type"]
- if interface_type in ["BackboneInterface", "TCPServerInterface"]:
- backbone_support = not RNS.vendor.platformutils.is_windows()
- connection_interface = "BackboneInterface" if backbone_support else "TCPClientInterface"
- remote_str = "remote" if backbone_support else "target_host"
- cfg_name = info["name"]
- cfg_remote = info["reachable_on"]
- cfg_port = info["port"]
- cfg_identity = info["transport_id"]
- cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
- cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
- cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
- cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
- cfg_identity_str = f"\n transport_identity = {cfg_identity}"
- info["config_entry"] = f"[[{cfg_name}]]\n type = {connection_interface}\n enabled = yes\n {remote_str} = {cfg_remote}\n target_port = {cfg_port}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
-
- if interface_type == "I2PInterface":
- cfg_name = info["name"]
- cfg_remote = info["reachable_on"]
- cfg_identity = info["transport_id"]
- cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
- cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
- cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
- cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
- cfg_identity_str = f"\n transport_identity = {cfg_identity}"
- info["config_entry"] = f"[[{cfg_name}]]\n type = I2PInterface\n enabled = yes\n peers = {cfg_remote}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
-
- if interface_type == "RNodeInterface":
- cfg_name = info["name"]
- cfg_frequency = info["frequency"]
- cfg_bandwidth = info["bandwidth"]
- cfg_sf = info["sf"]
- cfg_cr = info["cr"]
- cfg_identity = info["transport_id"]
- cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
- cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
- cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
- cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
- cfg_identity_str = f"\n transport_identity = {cfg_identity}"
- info["config_entry"] = f"[[{cfg_name}]]\n type = RNodeInterface\n enabled = yes\n port = \n frequency = {cfg_frequency}\n bandwidth = {cfg_bandwidth}\n spreadingfactor = {cfg_sf}\n codingrate = {cfg_cr}\n txpower = {cfg_netname_str}{cfg_netkey_str}"
-
- if interface_type == "WeaveInterface":
- cfg_name = info["name"]
- cfg_identity = info["transport_id"]
- cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
- cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
- cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
- cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
- cfg_identity_str = f"\n transport_identity = {cfg_identity}"
- info["config_entry"] = f"[[{cfg_name}]]\n type = WeaveInterface\n enabled = yes\n port = {cfg_netname_str}{cfg_netkey_str}"
-
- if interface_type == "KISSInterface":
- cfg_name = info["name"]
- cfg_frequency = info["frequency"]
- cfg_bandwidth = info["bandwidth"]
- cfg_modulation = info["modulation"]
- cfg_identity = info["transport_id"]
- cfg_netname = info["ifac_netname"] if "ifac_netname" in info else None
- cfg_netkey = info["ifac_netkey"] if "ifac_netkey" in info else None
- cfg_netname_str = f"\n network_name = {cfg_netname}" if cfg_netname else ""
- cfg_netkey_str = f"\n passphrase = {cfg_netkey}" if cfg_netkey else ""
- cfg_identity_str = f"\n transport_identity = {cfg_identity}"
- info["config_entry"] = f"[[{cfg_name}]]\n type = KISSInterface\n enabled = yes\n port = \n # Frequency: {cfg_frequency}\n # Bandwidth: {cfg_bandwidth}\n # Modulation: {cfg_modulation}{cfg_identity_str}{cfg_netname_str}{cfg_netkey_str}"
-
- except Exception as e: RNS.log(f"Error while generating config entry for interface: {e}", RNS.LOG_ERROR)
-
- return info["config_entry"] if "config_entry" in info else None
layout_object_details = """
#:import MDLabel kivymd.uix.label.MDLabel
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────